package com.caioweb.osa.mb;

import static com.caio.svn.Configuracoes.TXT_DADOS;
import static com.caio.svn.Configuracoes.TXT_ESTRUTURA;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.enterprise.context.ConversationScoped;
import javax.faces.bean.SessionScoped;
import javax.inject.Inject;

import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;

import com.caio.svn.GeraScriptLinux;
import com.caio.svn.UtilSvn;
import com.caioweb.osa.dao.ClienteDAO;
import com.caioweb.osa.dao.DAO;
import com.caioweb.osa.dao.HistoricoDAO;
import com.caioweb.osa.modelo.Ambiente;
import com.caioweb.osa.modelo.Cliente;
import com.caioweb.osa.modelo.Historico;
import com.caioweb.osa.modelo.TipoAmbienteCliente;
import com.caioweb.osa.modelo.Usuario;
import com.caioweb.osa.transacoes.interceptor.Transactional;
import com.mysql.jdbc.Util;

@SessionScoped
public class GeraScriptBean implements Serializable {

	@Inject
	private Historico historico;
	@Inject
	private ClienteDAO daoCliente;
	@Inject
	private DAO<Historico> daoh;
	@Inject
	private DAO<Usuario> daoUso;
	@Inject
	private DAO<Ambiente> dao;
	private List<Cliente> clientes = new ArrayList<Cliente>();
	@Inject
	private Ambiente ambiente;
	@Inject
	private Cliente cliente;
	@Inject
	private UsuarioLogado usuarioLogado;
	@Inject
	private DAO<TipoAmbienteCliente> daoTpAmbienteCliente;
	
	private List<TipoAmbienteCliente> ambienteClientes;
	
	private Integer idRevisaoRestaurada;
	private Long idtpAmbienteCliente;
	private String restaurada;
	private boolean baseRestaurada;
	private boolean finalizado;
	private GeraScriptLinux  geraScriptLinux;
	private String log = "";
	private Long idAmbiente;
	private StreamedContent fileDados;
    private StreamedContent fileEstrutura;
    private List<Ambiente> ambientes;
    
    
    @Transactional
	public void gerar() throws IOException, InterruptedException {
		this.ambiente = dao.buscaPorId(idAmbiente);
		this.historico.setAmbiente(ambiente);
		this.historico.setUsuario(daoUso.buscaPorId(usuarioLogado.getUsuario().getId()));
		
		if(baseRestaurada){
			if(validaBaseRestaurada()){
				this.historico.setRevisaoInicial(idRevisaoRestaurada);
			}else{
				return;
			}		
		}else{
			this.historico.setRevisaoInicial(ambiente.getNrinicial());
		}
		
		//inicia a criacao de script
		this.geraScriptLinux = new GeraScriptLinux(historico);
		finalizado = geraScriptLinux.executaCriacao(this);
		
		
		if(finalizado){
		this.historico.setData(new Date(System.currentTimeMillis()));
		this.ambiente.setNrinicial(historico.getRevisaoFinal());
		daoh.adiciona(historico);
		dao.atualiza(ambiente);
		UtilSvn.mensagem("Script gerado com sucesso!!" ,true);
		}
		
	}
    @Transactional
	public void selecionar(){
		 if(getAmbientes().isEmpty()){
			 limpa();
			 UtilSvn.mensagem("Nao existe nenhum ambiente desse tipo para esse cliente",true);
			 return;
		 }
		if(this.baseRestaurada){
			HistoricoDAO dao = new HistoricoDAO();
			Integer idRevisao = dao.buscaRevisaoBaseRestaurada(cliente.getId(),idtpAmbienteCliente);

			
			if(idRevisao != null){
				idRevisaoRestaurada = idRevisao;
			}else{
				UtilSvn.mensagem("Ambiente de "+AmbienteBean.EXTERNO+" nao existe,o numero de revisao devera ser preencido manualmente",true);
				return;
			}
		}
	}
    
	public void limpa() {
		this.cliente = new Cliente();
		this.historico= new Historico();
		this.ambiente = new Ambiente();
		this.idAmbiente = null;
		this.finalizado = false;
		this.baseRestaurada = false;
		this.log = "";
		this.idRevisaoRestaurada = null;
		
	}
	
	
	public boolean validaBaseRestaurada(){
		if(idRevisaoRestaurada == null || idRevisaoRestaurada < ambiente.getBranch().getRevisao()){
			UtilSvn.mensagem("O numero de revisao e inferior ao minimo do branch: "+ ambiente.getBranch().getRevisao(),true);
		return false;
		}
		return true;
		
	}
	@Transactional
	public List<Cliente> completaCliente(String sigla) {
		this.clientes = daoCliente.listaTodosComecaTemAmbiente(sigla);
		return clientes;
	}

	public Historico getHistorico() {
		return historico;
	}

	public void setHistorico(Historico historico) {
		this.historico = historico;
	}

	public ClienteDAO getDaoCliente() {
		return daoCliente;
	}

	public void setDaoCliente(ClienteDAO daoCliente) {
		this.daoCliente = daoCliente;
	}

	public List<Cliente> getClientes() {
		return clientes;
	}

	public void setClientes(List<Cliente> clientes) {
		this.clientes = clientes;
	}

	public Ambiente getAmbiente() {
		return ambiente;
	}

	public void setAmbiente(Ambiente ambiente) {
		this.ambiente = ambiente;
	}

	public Cliente getCliente() {
		return cliente;
	}

	public void setCliente(Cliente cliente) {
		this.cliente = cliente;
	}

	public DAO<Ambiente> getDao() {
		return dao;
	}

	public void setDao(DAO<Ambiente> dao) {
		this.dao = dao;
	}

	public UsuarioLogado getUsuarioLogado() {
		return usuarioLogado;
	}

	public void setUsuarioLogado(UsuarioLogado usuarioLogado) {
		this.usuarioLogado = usuarioLogado;
	}


	public Long getIdAmbiente() {
		return idAmbiente;
	}

	public void setIdAmbiente(Long idAmbiente) {
		this.idAmbiente = idAmbiente;
	}


	public GeraScriptLinux getGeraScriptLinux() {
		return geraScriptLinux;
	}

	public void setGeraScriptLinux(GeraScriptLinux geraScriptLinux) {
		this.geraScriptLinux = geraScriptLinux;
	}

	public String getLog() {
		return log;
	}

	public void setLog(String log) {
		this.log += log;
	}
	
	public boolean isBotao(){
		return (cliente.getId() != null && !finalizado);
	}

	public boolean isFinalizado() {
		return finalizado;
	}

	public void setFinalizado(boolean finalizado) {
		this.finalizado = finalizado;
	}
	
	public List<Historico> getHistoricos(){
		List<Historico> historicos = new ArrayList<Historico>();
		historicos.add(this.historico);
		return historicos;
	}
	
    public StreamedContent getFileEstrutura() throws FileNotFoundException {
        InputStream stream = new FileInputStream(this.historico.getArquivo()+ TXT_ESTRUTURA);  
        fileEstrutura = new DefaultStreamedContent(stream, "application/txt",  TXT_ESTRUTURA);
        return fileEstrutura;    
    }    
    
    public void setFileDados(StreamedContent file) throws FileNotFoundException {   
    	
        this.fileDados = file;    
    } 
    
    
    
    public StreamedContent getFileDados() throws FileNotFoundException {
    	 InputStream stream = new FileInputStream(this.historico.getArquivo()+ TXT_DADOS);  
         fileDados = new DefaultStreamedContent(stream, "application/txt", TXT_DADOS);
		return fileDados;
	}

	public void setFileEstrutura(StreamedContent fileEstrutura) {
		this.fileEstrutura = fileEstrutura;
	}


	public boolean isBaseRestaurada() {
		return baseRestaurada;
	}

	public void setBaseRestaurada(boolean baseRestaurada) {
		this.baseRestaurada = baseRestaurada;
	}

	public String getRestaurada() {
		return restaurada;
	}

	public Integer getIdRevisaoRestaurada() {
		return idRevisaoRestaurada;
	}

	public void setIdRevisaoRestaurada(Integer idRevisaoRestaurada) {
		this.idRevisaoRestaurada = idRevisaoRestaurada;
	}

	public void setRestaurada(String restaurada) {
		if(restaurada != null){
			baseRestaurada = restaurada.equals("sim")? true: false;
		}
		
		this.restaurada = restaurada;
	}
	
	public List<Ambiente> getAmbientes(){
		this.ambientes = this.cliente.getAmbientes();
		
		Iterator<Ambiente> lista = ambientes.iterator();
 		ambientes = new ArrayList<Ambiente>();
 		
		while(lista.hasNext()){
			Ambiente ambiente = lista.next();
			if(ambiente.getTipoAmbienteCliente().getId().equals(idtpAmbienteCliente)){
				
				if(baseRestaurada){
					
				   if(ambiente.getTpAmbiente().equals(AmbienteBean.INTERNO)){
						ambientes.add(ambiente);
				   }
					
				}else{
					ambientes.add(ambiente);
				}
				
			}
		}
		return this.ambientes;
	}

	public Long getIdtpAmbienteCliente() {
		return idtpAmbienteCliente;
	}

	public void setIdtpAmbienteCliente(Long idtpAmbienteCliente) {
		this.idtpAmbienteCliente = idtpAmbienteCliente;
	}
	
	public void setAmbientes(List<Ambiente> ambientes) {
		
		this.ambientes = ambientes;
	}
	@Transactional
	public List<TipoAmbienteCliente> getAmbienteClientes() {
		this.ambienteClientes = daoTpAmbienteCliente.listaTodos();
		return ambienteClientes;
	}

	public void setAmbienteClientes(List<TipoAmbienteCliente> ambienteClientes){

		this.ambienteClientes = ambienteClientes;
	}
	
	


	
	
	
}
